package com.mfs.proxy.client.transfer.http.request;

import com.mfs.common.utills.StringUtil;

import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Http 请求对象
 *
 * @author mfs
 * @date 2023/7/10 22:31
 **/
public class HttpRequest {
    private HttpRequestLine httpRequestLine = new HttpRequestLine();
    private HttpRequestHeader httpRequestHeader = new HttpRequestHeader();
    private HttpRequestBody httpRequestBody = new HttpRequestBody();
    private boolean valid = true;

    public HttpRequestLine getHttpRequestLine() {
        return httpRequestLine;
    }

    public void setHttpRequestLine(HttpRequestLine httpRequestLine) {
        this.httpRequestLine = httpRequestLine;
    }

    public HttpRequestHeader getHttpRequestHeader() {
        return httpRequestHeader;
    }

    public void setHttpRequestHeader(HttpRequestHeader httpRequestHeader) {
        this.httpRequestHeader = httpRequestHeader;
    }

    public HttpRequestBody getHttpRequestBody() {
        return httpRequestBody;
    }

    public void setHttpRequestBody(HttpRequestBody httpRequestBody) {
        this.httpRequestBody = httpRequestBody;
    }

    public boolean isValid() {
        return valid;
    }

    public void setValid(boolean valid) {
        this.valid = valid;
    }

    public byte[] getBytes() {
        byte[] line = httpRequestLine.getBytes();
        byte[] head = httpRequestHeader.getBytes();
        byte[] body = httpRequestBody.getBytes();
        byte[] res = new byte[line.length + head.length + body.length];
        System.arraycopy(line, 0, res, 0, line.length);
        System.arraycopy(head, 0, res, line.length, head.length);
        System.arraycopy(body, 0, res, line.length + head.length, body.length);
        return res;
    }

    public void decodeBody() {
        if (enableBodyDecode()) {
            httpRequestBody.decode(getBodyCharset());
        }
    }

    /**
     *
     * 响应体是否可解码
     */
    public boolean enableBodyDecode() {
        String contentType = httpRequestHeader.getHead("content-type").toLowerCase();
        return StringUtil.isNotEmpty(contentType) && (contentType.contains("text/") || contentType.contains("application/json"));
    }

    /**
     * 获取当前解析的请求体的字符集编码,
     * 获取不到则返回默认字符集
     * */
    private Charset getBodyCharset() {
        String contentType = httpRequestHeader.getHead("content-type");
        if (StringUtil.isNotBlank(contentType)) {
            Pattern pattern = Pattern.compile("charset\\s*=\\s*\\S+;");
            Matcher matcher = pattern.matcher(contentType);
            if (matcher.matches()) {
                String charsetParam = matcher.group();
                if (StringUtil.isNotBlank(charsetParam)) {
                    String charset = charsetParam.replaceAll("charset", "").replace("=", "").replaceAll(";", "").trim();
                    try {
                        return Charset.forName(charset);
                    } catch (UnsupportedCharsetException e) {
                    }
                }
            }
        }
        return Charset.defaultCharset();
    }

    @Override
    public String toString() {
        return httpRequestLine + "\r\n" + httpRequestHeader + "\r\n\r\n" + httpRequestBody;
    }
}
